﻿// 0805train01.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <algorithm>
#include <limits.h>

using namespace std;

/*
 头和结尾都是元音字母（aeiouAEIOU）的字符串为元音字符串，其中混杂的非元音字母数量为其瑕疵度。比如:
- "a"，"aa"是元音字符串，其瑕疵度都为 0
- "aiur"不是元音字符串（结尾不是元音字符）
- "abira"是元音字符串，其瑕疵度为 2
给定一个字符串，请找出指定瑕疵度的最长元音字符子串，并输出其长度，如果找不到满足条件的元音字符子串，输出 0。
子串：字符串中任意个连续的字符组成的子序列称为该字符串的子串。

输入描述
首行输入是一个整数，表示预期的瑕疵度flaw，取值范围[0, 65535]。
接下来一行是一个仅由字符a-z和A-Z组成的字符串，字符串长度(0, 65535]。

输出描述
输出为一个整数，代表满足条件的元音字符子串的长度。

输入
0
asdbuiodevauufgh
输出
3
 */

bool IsTargetChar(unordered_set<char>oh_set, char oh_char)
{
    return !oh_set.count(oh_char);
    //------
}

unordered_set<char>GetTargetSet()
{
    string target_str = "aeiouAEIOU";
    unordered_set<char>oh_set;
    for (auto&oh_char:target_str)
    {
        oh_set.insert(oh_char);
    }
    return oh_set;
}

void solve01(string &oh_str, int limit)
{
    unordered_set<char>oh_set = GetTargetSet();
    int left_index = 0;
    int str_size = oh_str.size();
    if (limit==0)
    {
        int result = 0;
        int right_index = 0;
        while (right_index < str_size)
        {
            char right_char = oh_str[right_index];
            if (IsTargetChar(oh_set, right_char))
            {
                result = max(result, right_index - left_index);
                right_index += 1;
                left_index = right_index;
                continue;
            }

            result = max(result, right_index - left_index + 1);
            right_index += 1;
        }

        cout << result;
        return;
    }

    int result = -1;
    int target_count = 0;
    for (int right_index=0; right_index<str_size; right_index++)
    {
        char right_char = oh_str[right_index];
        if (IsTargetChar(oh_set, right_char))
        {
            target_count += 1;
        }

        while (left_index<=right_index&& 
            (target_count > limit || IsTargetChar(oh_set, oh_str[left_index]))
            )
        {
            char left_char = oh_str[left_index];
            if (IsTargetChar(oh_set,left_char))
            {
                target_count -= 1;
            }
            left_index += 1;
        }
        char left_char = oh_str[left_index];
        if (oh_set.count(right_char)&& oh_set.count(left_char)&&target_count==limit)
        {
            result = max(result, right_index - left_index + 1);
        }
        //for-----
    }

    if (result==-1)
    {
        cout << 0;
        return;
    }
    
    cout << result;
    //solve01
}

/*
宝石的价格标记为gems[i],0<=i<n，n = gems.length。
宝石可同时出售0个或多个，如果同时出售多个，则要求出售的宝石编号连续；
例如客户最大购买宝石个数为m，购买的宝石编号必须为gems[i],gems[i+1]...gems[i+m-1](0<=i<n,m<=n)。
假设你当前拥有总面值为value的钱，请问最多能购买到多少个宝石。如无法购买宝石，则返回0。
输入描述
第一行输入n，参数类型为 int，取值范围：[0,10^6]，表示橱窗中宝石的总数量。
之后n行分别表示从第0个到第n-1个宝石的价格，即gems[0]到gems[n-1]的价格，类型为int，取值范围：(0,1000]。
之后一行输入v，类型为int，取值范围：[0,10^9]表示你拥有的钱。
输出描述
输出int类型的返回值，表示最大可购买的宝石数量。

示例1
输入
7
8
4
6
3
1
6
7
10

输出
3

gems = [8,4,6,3,1,6,7], value = 10
最多购买的宝石为gems[2]至gems[4]或者gems[3]至gems[5]
 */

void solve02(vector<int>&oh_vec, int target)
{
    if (oh_vec.empty())
    {
        cout << 0;
        return;
    }

    int left_index = 0;
    int vec_size = oh_vec.size();

    int result = -1;
    int oh_sum = 0;
    for (int right_index=0; right_index<vec_size; right_index++)
    {
        int curr_num = oh_vec[right_index];
        oh_sum += curr_num;

        while (oh_sum>target)
        {
            int left_num = oh_vec[left_index];
            oh_sum -= left_num;
            left_index += 1;
        }

        if (oh_sum<=target)
        {
            result = max(result, right_index-left_index+1);
        }
    }

    cout << result;
    //solve02
}


/*
 给定一个矩阵，包含N*M个整数，和一个包含K个整数的数组，
 现在要求在这个矩阵中找一个宽度最小的子矩阵，要求子矩阵包含数组中所有的整数

输入描述
第一行输入两个正整数N，M，表示矩阵大小。
接下来N行M列表示矩阵内容。下一行包含一个正整数K。
下一行包含K个整数，表示所需包含的数组，K个整数可能存在重复数字。
所有输入数据小于1000。

输出描述
输出包含一个整数，表示满足要求子矩阵的最小宽度，若找不到，输出-1

输入
2 5（2行5列数组）
1 2 2 3 1
2 3 2 3 2
3（数组里包含3个整数）
1 2 3


输入
2 5
1 2 2 3 1
2 3 2 3 2
3
1 2 3
输出
2
 */



unordered_map<int,int>GetTargetMap(vector<int>& target_vec)
{
    unordered_map<int, int>target_map;

    for (auto&num:target_vec)
    {
        target_map[num] += 1;
    }
    
    return target_map;
	//GetTargetMap
}

vector<int>GetCurrVec(const vector<vector<int>>& oh_vec, int left_index, int right_index)
{
    int height_size = oh_vec.size();
    int width_size = right_index - left_index + 1;
    vector<int>curr_vec(width_size*height_size);

    if (width_size == 1)
    {
        for (int i = 0; i < height_size; i++)
        {
            curr_vec[i] = oh_vec[i][right_index];
        }
    }
    else
    {
        int count = 0;
        for (int w_1=left_index; w_1<=right_index; w_1++)
        {
            for (int h_2=0; h_2<height_size; h_2++)
            {
                curr_vec[count] = oh_vec[h_2][w_1];
                count++;
            }
        }
    }


    return curr_vec;
}

bool IsComplete(const unordered_map<int, int>& origin_map,
    const vector<vector<int>>&oh_vec,
    int left_index,
    int right_index
)
{
    vector<int>curr_vec = GetCurrVec(oh_vec, left_index, right_index);
    unordered_map<int, int>target_map;
    
    for (auto& num : curr_vec)
    {
        if (origin_map.count(num))
        {
            target_map[num] += 1;
        }
    }

    bool result = true;

    for (auto map_item : origin_map)
    {
        int item_key = map_item.first;
        int item_count = map_item.second;
        if (target_map[item_key] < item_count)
        {
            result = false;
            break;
        }

    }

    return result;
}

void solve03(vector<vector<int>>&oh_vec, vector<int>&target_vec)
{
    //target_vec扫一遍存到map中，
    //1遍历map，map里面所有value加起来为0，说明找到了
    //2尝试收缩左针，如果缩到map里面的元素，那么-1
    //3map里所有元素不为0，跳出while，停止收缩，继续扩右窗

    unordered_map<int, int>origin_map = GetTargetMap(target_vec);
    

    //cout << IsComplete(origin_map, target_map) << endl;

    int left_index = 0;
    int vec_width_size = oh_vec[0].size();
    int vec_height_size = oh_vec.size();

    int result = INT_MAX;
    for (int right_index=0; right_index< vec_width_size; right_index++)
    {
        vector<int>curr_vec = GetCurrVec(oh_vec, left_index, right_index);
        

        //说明此时已达到目标，尝试收缩左窗
        while (IsComplete(origin_map, oh_vec,left_index,right_index) && left_index<=right_index)
        {
            result = min(result, right_index - left_index + 1);

            left_index += 1;
        }
    	//for------
    }

    if (result==INT_MAX)
    {
        cout << -1;
        return;
    }
    cout << result;

	//solve03
}

int main()
{
	{
        //2 5
		//1 2 2 3 1
		//2 3 2 3 2
		//3
		//1 2 3
        //int vec_height, vec_width;
        //cin >> vec_height >> vec_width;

        //vector<vector<int>>oh_vec(vec_height);
        //for (int h_1=0; h_1< vec_height; h_1++)
        //{
        //    vector<int>mini_vec(vec_width);
        //    for (int i=0; i<vec_width; i++)
        //    {
        //        cin >> mini_vec[i];
        //    }
        //    oh_vec[h_1] = mini_vec;
        //}

        //for (auto&mini_vec:oh_vec)
        //{
	       // for (auto&num:mini_vec)
	       // {
        //        cout << num << ' ';
	       // }
        //}
        //int target_vec_size;
        //cin >> target_vec_size;

        //vector<int>target_vec(target_vec_size);
        //for (int i=0; i<target_vec_size;i++)
        //{
        //    cin >> target_vec[i];
        //}

        //for (auto&num:target_vec)
        //{
        //    cout << num << ' ';
        //}

        vector<int>vec_1 = { 1,2,2,3,1 };
        vector<int>vec_2 = { 2,3,2,3,2 };
        vector<vector<int>>oh_vec = { vec_1,vec_2 };
        vector<int>target_vec = {1,2,3,3};

        solve03(oh_vec, target_vec);

        return 0;
	}


	{
        //gems = [8,4,6,3,1,6,7], value = 10 3
        //gems = [6,1,3,1,8,9,3,2,4], value = 15 4

        int count;
        cin >> count;
        
        if (count==0)
        {
            int target;
            cin >> target;
            cout << 0;
        }
        else
        {
            vector<int>oh_vec(count);
            for (int i=0; i<count; i++)
            {
                cin >> oh_vec[i];
            }
            int target;
            cin >> target;

            solve02(oh_vec, target);
            //cout << target;
        }

        //vector<int>oh_vec = { 6, 1, 3, 1, 8, 9, 3, 2, 4 };
        //int value = 15;

        //solve02(oh_vec, value);

        return 0;
	}

    //1
    //aabeebuu 5
    //2
	//aeueo 0
    //0
	//asdbuiodevauufgh 3
    //string oh_str = "aabeebuu";
    //int limit = 1;
    int limit;
    cin >> limit;
    string oh_str;
    cin >> oh_str;
    solve01(oh_str, limit);
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
